package main

import (
	"fmt"
	"net"
	"time"

	"gitee.com/zhaoqinghuan/rpc/transport"
)

func main() {
	udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5678") // 解析一个 UDP 地址。该函数将字符串形式的地址解析为 *net.UDPAddr 类型
	transport.CheckError(err)
	// UDP 中的这个 conn(虚拟连接)是可以复用的，可能会有多个客户端都通过这个连接来发送消息
	conn, err := net.ListenUDP("udp", udpAddr) // 监听 UDP 连接， UDP不需要创建连接，所以不需要像TCP那样通过Accept()创建连接，这里的conn是个假连接
	transport.CheckError(err)
	conn.SetReadDeadline(time.Now().Add(30 * time.Second)) // 置连接的读取超时时间为 30 秒。从当前时间开始，30 秒后停止读取。如果在 30 秒内没有收到任何数据，将发生读取超时错误
	defer conn.Close()                                     // 延迟执行 conn.Close()，在当前函数返回之前关闭连接

	time.Sleep(5 * time.Second)  //故意多sleep一会儿，让client多发几条消息过来
	request := make([]byte, 256) // 创建一个 256 字节大小的缓冲区，用于存储接收到的数据。
	for {
		// 读取到的数据长度, 发送数据的远程地址
		read_len, remoteAddr, err := conn.ReadFromUDP(request) //UDP是面向报文的，一次read刚好读好一条数据。如果由于buffer小导致读不完一条完整的消息（也取不到remoteAddr），则后半部分下次read也读不到了
		transport.CheckError(err)
		fmt.Printf("receive request %s from %s\n", string(request[:read_len]), remoteAddr.String()) // 将接收到的字节数据转换为字符串，只转换实际读取的部分
	}
}
